﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.SqlClient;

using Fuse8.DomainFramework.Common;
using Fuse8.DomainFramework.DataAccess.SqlDatabase;

using Fuse8.ContentManagementFramework.Domain;
using Fuse8.ContentManagementFramework.Domain.Commands.CommandParameters;
using System.Data;

namespace Fuse8.ContentManagementFramework.DataAccess.SqlAccess.Mappers
{
    internal class CmsEntityPropertyDataMapper: BaseSqlEntityDataMapper<CmsEntityMetaField, int>
    {
        private static BaseSqlEntityDataMapper<CmsEntityMetaField, int> _based = new BaseSqlEntityDataMapper<CmsEntityMetaField, int>();

        private static Dictionary<string, Func<object, IList<SqlParameter>>> _mappersTo = new Dictionary<string, Func<object, IList<SqlParameter>>>();

        static CmsEntityPropertyDataMapper()
        {
            _mappersTo.Add("cms_sp_CreateEntityProperty", CreateMapperForEntityPropertyCreate);
        }

        public CmsEntityPropertyDataMapper()
            : base(new[] { "EntityMetaFieldLinkId" })
        { }

        public override IList<SqlParameter> MapTo(string sp, object parameter, bool isForCreate)
        {
            Guard.ArgumentNotEmpty(sp, "sp");
            
            return _mappersTo.ContainsKey(sp) && parameter != null ?
                _mappersTo[sp](parameter) :
                base.MapTo(sp, parameter, isForCreate);
        }

        public override CmsEntityMetaField MapFrom(string sp, SqlDataReader reader)
        {
            Guard.ArgumentNotEmpty(sp, "sp");
            Guard.ArgumentNotNull(reader, "reader");

            CmsEntityMetaField result = new CmsEntityMetaField
            {
                Id = reader.GetInt32(reader.GetOrdinal("EntityMetaFieldId")),
                EntityMetaFieldLinkId = !reader.IsDBNull(reader.GetOrdinal("EntityMetaFieldLinkId")) ?
                     reader.GetInt32(reader.GetOrdinal("EntityMetaFieldLinkId")) :
                     0,
                MetaFieldName = reader.GetString(reader.GetOrdinal("MetaFieldName")),
                MetaFieldDescription = !reader.IsDBNull(reader.GetOrdinal("MetaFieldDescription")) ?
                      reader.GetString(reader.GetOrdinal("MetaFieldDescription")) :
                      null,
                IsSystem = reader.GetBoolean(reader.GetOrdinal("IsSystem")),
                MetaFieldType = reader.GetString(reader.GetOrdinal("MetaFieldType"))
            };

            return result;
        }

        private static IList<SqlParameter> CreateMapperForEntityPropertyCreate(object parameter)
        {
            IList<SqlParameter> result = new List<SqlParameter>();

            var concreteParameter = parameter as CmsEntityPropertyCreateCommandParameter;
            if (concreteParameter != null)
            {
                result.Add(new SqlParameter("MetaFieldName", concreteParameter.MetaFieldName));
                result.Add(new SqlParameter("MetaFieldType", concreteParameter.MetaFieldType));
                result.Add(new SqlParameter("EntityTypeParameter", concreteParameter.EntityType));
            }

            return result;
        }
    }
}
